プログラムではアクセスキー/シークレットキーを使わずにRoleを利用する
渡辺です。
最近は、システムの開発支援としてAWS環境構築などに関わる事が多いです。 そこで、開発者側視点で押さえておきたいAWSのノウハウや基礎知識を書いて展開してみたいと思います。
今回はEC2で動くプログラムがアクセスキー/シークレットキーを使わずにRoleを利用すべき、という話です。
Roleとは?
RoleはIAMの機能のひとつで、アクセスキー/シークレットキーを使わずに各種AWSリソースにアクセスすることができます。 例えば、EC2インスタンスからS3にオブジェクトを書き込んだり、SNSにメッセージを送信したりする場合に利用できます。
アクセスキー/シークレットキーとの違い
ひとことで言えば、Roleはアクセスキー/シークレットキーに比べ、キーの管理をする必要がありません。 ただし、EC2インスタンスにしか割り当てることしかできません。
キー管理が不要
アクセスキー/シークレットキーは、ペアで環境変数や設定ファイルに登録しておく必要があります。 また、ある程度の期間でローテーションをすることが推奨されています。 誤ってリポジトリにコミットしてしまったり、なんらかの理由でキーが漏洩してしまうとどこからでも操作できてしまうため、慎重に管理しなければなりません。 できることならば管理したくないのが心情です。
Roleを使えば、キーの管理は不要になります。
EC2の立ち上げ時に割り当てる
RoleはEC2の立ち上げ(Launch)時に指定します。 言い換えると、ローカル環境などでは利用できません。 ローカル環境などでAWS-SDKなどを利用する場合は、アクセスキー/シークレットキーが必要です。
なお、現在時点では、起動中のインスタンスや、停止しただけのインスタンスにRoleを再割当てできません。 あらかじめ空のRoleを作成しておき、割当てだけはしておくと良いでしょう。
Roleの利用
簡単なサンプルを見ながら、Roleを利用してみましょう。
Roleを作成する
Roleを作成するのは簡単です。 IAMメニューからRolesを開き、Create Roleボタンをクリックしてください。
Roleには多くの機能がありますが、EC2から利用する機能を制御するためのRoleを作成する場合は、AWS Service RolesのAmazon EC2を選択しましょう。
セキュリティポリシーは細かく制御できますが、後からでも簡単に変更できます。 とりあえずは、テンプレートから、Power User AccessかRead Only Accessを選ぶとよいでしょう。
このようにして、「ec2-user」や「default-ec2-role」といった名前のRoleを作成しておきましょう。
Roleを適用したEC2を起動する
Roleを適用したEC2を起動するには、立ち上げ時の設定画面で、IAM roleを設定します。
後は通常通りにEC2インスタンスを起動してください。 なお、繰り返しになりますが、IAM Roleはこの立ち上げ時にしか設定できないので注意してください。
もし、既存のインスタンスにIAM Roleを適用したい場合は、停止後AMIを作成し、インスタンスを作り直す必要があります。
AWS CLIを利用してみる
AWS CLIでSNSにメッセージを送ってみます。
$ aws sns publish --region=ap-northeast-1 --topic-arn=arn:aws:sns:ap-northeast-1:999999999999:cm-shuji-sns --message=TEST { "MessageId": "8b30213d-6a0d-5216-9166-6dbdc6e54104" }
このように適切なRoleがあれば、アクセスキー/シークレットキーの設定は不要です。 なお、アクセスキー/シークレットキーを利用する場合は、次のように定義ファイルまたは環境変数に定義しなければなりません。
~/.aws\credentials
[default] aws_access_key_id = your_access_key_id aws_secret_access_key = your_secret_access_key
~/.bash_profile
export AWS_ACCESS_KEY_ID=your_access_key_id export AWS_SECRET_ACCESS_KEY=your_secret_access_key
Ruby AWS SDKを利用してみる
プログラムがrubyであるならば、Ruby AWS SDKをgemでインストールして利用します。
$ gem install aws-sdk --no-ri --no-rdoc
サンプルコードは次のようになります。
require 'aws-sdk' AWS.config({ :region => 'ap-northeast-1' }) sns = AWS::SNS.new topic = sns.topics['arn:aws:sns:ap-northeast-1:999999999999:cm-shuji-sns'] result = topic.publish 'TEST' puts result
ここでもアクセスキー/シークレットキーを利用していません。
アクセスキー/シークレットキーを利用する場合は、次のようにAWS.Configで設定するか、またはSNSオブジェクトのコンストラクタに渡す必要があります。
AWS.config({ :access_key_id => 'ACCESS_KEY_ID', :secret_access_key => 'SECRET_ACCESS_KEY', :region => 'ap-northeast-1' })
sns = AWS::SNS.new({ :access_key_id => 'ACCESS_KEY_ID', :secret_access_key => 'SECRET_ACCESS_KEY' })
ローカル開発環境での扱い
プログラムをローカルの開発環境で作成し、動作確認をAWSで行うケースは多いと思います。 そのような場合は、ローカル環境とAWS環境でプロファイルなどを切り替えると良いでしょう。
例えば、RailsのENVや、JavaのDIなどの仕組みを使い、ローカル環境とAWS環境で設定を切り替えてください。
まとめ
Roleを利用することで、アクセスキー/シークレットキーの管理から解放されます。 ローテーションの手間もありません。 EC2上のプログラムからAWSのサービスにアクセスする場合は、Roleを使いましょう。
なお、どうしてRoleを使うとアクセスキー/シークレットキーの設定が不要かという疑問については、IAM Roleの仕組みを追う – なぜアクセスキーを明記する必要がないのかを参照ください。